/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sun.scheduler.core.scheduling;

import java.util.Comparator;
import sun.scheduler.core.ScheduleGraph;
import sun.scheduler.core.job.Job;
import sun.scheduler.core.resource.Resource;
import sun.scheduler.core.resource.ResourceProfile;
import sun.scheduler.core.resource.ResourceProfileMap;

/**
 * A comparator that compares two JobInfos by the amount of time of which this
 * JobInfo can be delayed without affecting the overall project time.
 *
 * @author mfj
 */
public class DIncreaseComp implements Comparator<Job>
{

    /**
     * The {@link CurveState} Scheduling
     */
    public final static Job.CurveState CS = Job.CurveState.Scheduling;
    // the used ResourceProfileMap to identify each resource with its profile
    private ScheduleGraph sGraph;
    private ResourceProfileMap rProfiles;
    public DIncreaseComp(ScheduleGraph sGraph)
    {
        this.sGraph = sGraph;
        this.rProfiles = sGraph.getResourceProfiles();
    }

    private long delay(Job job)
    {
        ResourceProfile profile = rProfiles.getResourceProfile(job.resource);
        long result = profile.next(job.getEarliestStartTime(CS), job.getDuration(CS), (int) job.getAmountOfResources(CS));
        return (result - job.getLatestEndTime(CS) - job.getDuration(CS));
    }

    

    private long buffer(Job job)
    {
        return (job.getLatestEndTime(CS) - job.getDuration(CS) - job.getEarliestStartTime(CS));
    }

    
    
    private long totalBuffer(Job job, int depth)
    {
        long result = Math.max(delay(job), 0);

        if (job.getSuccessors().isEmpty() || depth == 0)
            return result;

        long max = Long.MIN_VALUE;
        for (int pred : job.getSuccessors())
        {
            max = Math.max(totalBuffer(sGraph.getJob(pred), depth -1), max);
        }

        return result + max;
    }

    /**
     * {@inheritDoc}. Compares two jobs by the asumed overall delay of project
     * time
     * {@code (nextStart(t1) - buffer(t1)) - (nextStart(t2) - buffer(t2))}
     */
    @Override
    public int compare(Job t1, Job t2)
    {
        return Double.compare( totalBuffer(t1, 3), totalBuffer(t2, 3));
    }

}
